Skip to content

ci: build, smoke-test and publish the Xiongmai openipc-xm images - #14

Merged
widgetii merged 2 commits into
openipcfrom
ci/build-xm
Oct 17, 2026
Merged

widgetii merged 2 commits into
openipcfrom
ci/build-xm

Conversation

@widgetii

Copy link
Copy Markdown
Member

Adds build-xm.yml for the new openipc-xm branch (#13), the same shape as build-hisilicon.yml:

  • Jobs: resolve → build (xm510/xm530/xm550, NOR fit check ≤ 256 KiB) → qemu → qemu_smoke → release / publish. Release and publish run on dispatch only.
  • No hold: every SoC has a qemu-hisilicon machine, so every image is smoke-tested and gated.
  • Smoke test: each NOR image boots in place from an 8 MiB flash image, twice, with the part powering up under the per-block protection Xiongmai bootloaders leave on (xm-sfc.wps, qemu-hisilicon#150).
    • It passes on Hit Ctrl-C.
    • It fails if the second boot finds a bad env CRC. That would mean the first boot's saveenv was dropped because the driver didn't clear the protection.
  • Release and publish:
    • release uploads to a new xiongmai tag.
    • publish uploads to OpenIPC/firmware latest (no u-boot-xm* names there today) and reports --source uboot to openipc.org with a uboot-xm-… build id, sharing hisilicon's concurrency group.
    • openipc.org keeps the newest uboot build per file name, so the two workflows don't displace each other.
  • Trigger: pull_request runs only when this workflow file changes, so other openipc PRs don't start the xiongmai matrix.
  • Docs: README and CLAUDE.md describe the branch and the workflow.

Checked locally: the smoke script as written passes on all three SoCs against qemu-hisilicon master. This PR's own run builds the current openipc-xm.

build-xm.yml has build-hisilicon.yml's shape: resolve the openipc-xm
revision once, build xm510/xm530/xm550 one per leg with the 256 KiB NOR
fit check, build qemu-hisilicon once, smoke-test every image, then
release (own `xiongmai` tag) and publish (OpenIPC/firmware latest plus
the openipc.org report) on dispatch only.

Every SoC has a qemu-hisilicon machine, so none is held. The smoke test
boots each NOR image in place from an 8 MiB flash image twice, with the
part powering up under the per-block protection Xiongmai bootloaders
leave on (xm-sfc.wps): it passes on the autoboot prompt, and fails if
the second boot finds a bad environment CRC -- the first boot's saveenv
dropped because the driver did not clear the protection. Checked locally
with the smoke script as written, against qemu-hisilicon with u-boot#150.

The pull_request trigger is limited to changes to this file, so other
openipc pull requests do not start the xiongmai matrix. publish shares
build-hisilicon's concurrency group; openipc.org keeps the newest uboot
build per file name, so the two workflows' pushes do not displace each
other's files.

README and CLAUDE.md describe the openipc-xm branch and the workflow.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Build, smoke-test, and publish Xiongmai U-Boot images

✨ Enhancement ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add CI builds and 256 KiB NOR fit checks for XM510, XM530, and XM550.
• Gate releases on two protected-flash QEMU boots that verify saved environment persistence.
• Document the Xiongmai branch and add dispatch-only release and publishing paths.
Diagram

graph TD
  R["Resolve revision"] --> B["Build NOR images"] --> S["QEMU smoke gate"] --> P["Publish images"] --> F[("Firmware latest")]
  Q["Build QEMU"] --> S
  S --> L[("Xiongmai release")]
  P --> W[("openipc.org records")]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Parameterize the existing HiSilicon workflow
  • ➕ Keeps common build, artifact, and publishing logic in one place.
  • ➖ Adds family-specific branches to a mature workflow and increases regression risk for HiSilicon releases.
2. Pin the QEMU revision
  • ➕ Makes the protected-flash smoke test reproducible across runs.
  • ➖ Requires deliberate updates to receive machine-model fixes.

Recommendation: Keep the separate Xiongmai workflow: its three-SoC, two-boot gate differs enough to justify family isolation. Consider extracting shared publishing logic later if duplication grows, and pin a tested QEMU revision once the required WPS support is available.

Files changed (3) +423 / -0

Documentation (2) +71 / -0
CLAUDE.mdDocument Xiongmai branch and CI invariants +24/-0

Document Xiongmai branch and CI invariants

• Describes the openipc-xm branch, workflow triggers, two-boot smoke-test criterion, and release and publishing behavior.

CLAUDE.md

README.mdAdd Xiongmai build and workflow guidance +47/-0

Add Xiongmai build and workflow guidance

• Adds a workflow badge, branch listing, supported SoCs, build instructions, and CI and release guidance. Explains run-in-place NOR boot and the flash-protection behavior covered by smoke testing.

README.md

Other (1) +352 / -0
build-xm.ymlAdd gated Xiongmai build and publishing workflow +352/-0

Add gated Xiongmai build and publishing workflow

• Adds revision-pinned NOR builds for three SoCs with partition-fit checks, then smoke-tests each image twice in QEMU with flash protection enabled. Dispatch-only jobs upload gated artifacts to the Xiongmai release or OpenIPC/firmware and report the published build to openipc.org.

.github/workflows/build-xm.yml

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Smoke tests stop before QEMU boots ✓ Resolved
Description
The flash-creation command pipes an infinite tr stream into head, which closes the pipe after 8
MiB and causes tr to exit with SIGPIPE. In the smoke step’s default Bash error-handling mode, that
nonzero pipeline result stops every SoC leg before the image is copied into flash or QEMU starts.
Code

.github/workflows/build-xm.yml[214]

+          tr '\0' '\377' < /dev/zero | head -c 8388608 > /tmp/flash.bin
Evidence
The finite head consumer follows an infinite producer, and flash creation precedes both the image
overlay and QEMU launch. The existing HiSilicon smoke test uses dd rather than a truncated
producer pipeline.

.github/workflows/build-xm.yml[208-225]
.github/workflows/build-hisilicon.yml[290-300]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The infinite `tr` producer receives SIGPIPE when `head` has written 8 MiB, making the smoke step fail before booting QEMU.
## Fix Focus Areas
- .github/workflows/build-xm.yml[213-215]
## Recommended Fix
Create an exactly 8 MiB erased flash file without an infinite-producer pipeline that fails under `pipefail`, then retain the U-Boot image overlay.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Oversized NOR images pass the fit gate ✓ Resolved
Description
check_kind divides the image’s byte count by 1024 before comparing it with the 256 KiB partition
limit, discarding any remainder. An image between 262,145 and 263,167 bytes therefore passes the
check despite extending beyond the boot partition into the environment area.
Code

.github/workflows/build-xm.yml[R115-117]

+              size_kb=$(( $(stat -c %s "$f") / 1024 ))
+              echo "- $f: [${size_kb}KB/${limit_kb}KB]"
+              if [ "$size_kb" -gt "$limit_kb" ]; then
Evidence
The workflow states that NOR boot ends at 256 KiB, but integer division makes every image from one
to 1,023 bytes above that boundary compare as 256 KiB.

.github/workflows/build-xm.yml[98-124]
CLAUDE.md[75-79]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Rounding image sizes down to whole KiB lets slightly oversized NOR images pass the partition-fit gate.
## Fix Focus Areas
- .github/workflows/build-xm.yml[107-120]
## Recommended Fix
Compare the raw `stat` byte count against `limit_kb * 1024`; round only values displayed in diagnostic messages.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can see how risky a PR is at a glance with blast radius labels

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread .github/workflows/build-xm.yml Outdated
Comment thread .github/workflows/build-xm.yml Outdated
…sh fill

- The partition-fit check compares bytes: dividing by 1024 first let an
  image up to 1023 bytes past 256 KiB through, into the environment.
- The erased 8 MiB flash image comes from a finite dd | tr, not an
  infinite tr cut off by head, which dies of SIGPIPE under pipefail.
@widgetii
widgetii merged commit e3f72a1 into openipc Oct 17, 2026
82 checks passed
@widgetii
widgetii deleted the ci/build-xm branch October 17, 2026 08:32
widgetii added a commit that referenced this pull request Oct 22, 2026
OpenIPC/u-boot-xmedia stopped publishing on 2026-10-16 (#14), and
OpenIPC/firmware `latest` has carried this tree's -nor/-nand builds of
its SoCs since (hi3516ev200/ev300, hi3518ev300, hi3516dv200, the
gk7205v200 family, gk7205v500/v510/v530). Their fmc100 ID tables lacked
36 SPI NAND and 8 SPI NOR chips the xmedia builds identified, so a camera
with one of them lost its flash: a NAND U-Boot found "0 MiB", a NOR
U-Boot fell back to another vendor's profile, or to "unknown", 4 MiB.

SPI NAND, appended after the existing entries (the driver takes the
first ID-prefix match, so they cannot shadow one above):
  Micron MT29F1G01ABA/ABB, MT29F2G01ABA/ABB, MT29F4G01ADAG/ABBFDWB;
  GigaDevice GD5F1GM7UEYIG (xmedia 6910ce1a9), GD5F1GQ4UAYIG,
  GD5F2GQ4UAYIG, GD5F4GQ4UAYIG, GD5F4GQ4RAYIG, GD5F4GQ4RBYIG,
  GD5F4GQ6RE9IG;
  ESMT F50L512M41A, F50L1G41A, F50L1G41LB-104YG2ME;
  Winbond W25N02JWZEIF, W25N02KVZEIR; Macronix MX35LF2GE4AB,
  MX35LF2G24AD, MX35UF4GE4AD; ATO ATO25D1GA; Paragon PN26G01A/G02A;
  Foresee FM25S01-DND-A-G, FM25S01A; ALLIANCE AFS1GQ4UAC/AFS2GQ4UAD;
  Toshiba TH58CYG3S0H; HeYangTek HYF1GQ4UAACAE, HYF2GQ4UAACAE,
  HYF4GQ4UAACBE; Etron EM73C044VCC-H, EM78D044VCF-H, EM78E044VCA-H,
  EM78F044VCA-H.
Skipped as already identified by an existing entry with the same ID:
GD5F2GQ4U9IGR/BYIG, XT26G01B, and the 31 chips both tables share. The
read/write/erase ops the new entries use are declared with the others.

SPI NOR (longest exact ID match wins, so order does not matter):
S25FL256S, XT25F16BSSIGU, MT25QL256A, F25L64QA, GD25Q256,
W25Q256JW-IQ, W25Q256JWFIM, W25Q512NW-IM (xmedia 31f87ca2b and later).
F25L64QA used xmedia's spi_driver_f25l64q, whose fields equal
spi_driver_no_qe, so it uses that. The NOR clock limits
(CONFIG_FMC_SPI_NOR_*_CLK_MAX) apply to them as to every entry.

Entries copied from OpenIPC/u-boot-xmedia master (bfbba0e5a); driver
cores (fmc100.c, fmc100_spi_general.c, the spi_nand_info and
spi_nor_info structs) match between the trees.

Checked in qemu-hisilicon, the FMC's READ_ID overridden with
-global hisi-fmc.nand-jedec / flash-jedec, published latest U-Boot vs
this build:
- SPI NAND, gk7205v200, hi3516ev300 and gk7205v500: GD5F1GM7 (0xc8 0x91,
  the model's default), GD5F1GQ4UAYIG (0xc8 0xf1), MT29F2G01ABA
  (0x2c 0x24), W25N02KV (0xef 0xaa 0x22): published "0 MiB", this build
  'Name:"..."' and 128/256 MiB; W25N01GV (0xef 0xaa 0x21) 128 MiB on both.
  GD5F4GQ6RE9IG (0xc8 0x45), hi3516ev300 and gk7205v200: published
  'Cannot found a valid SPI Nand Device', this build 'Name:"GD5F4GQ6RE9IG"'.
- SPI NOR, hi3516ev300 and gk7205v200: W25Q256JW (0xef 0x60 0x19) and
  W25Q512NW (0xef 0x80 0x20) published "unknown" 4MB, this build 32MB /
  64MB; GD25Q256 and XT25F16B published under W25Q256JVFIQ /
  GD25Q16ESIG, this build under their own names; W25Q128 unchanged.
hi3516ev300, gk7205v200, gk7205v500 and hi3516cv300 build (NOR, NAND),
within their boot areas, with no new warnings. Not run on hardware.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant